var fs = require('fs');

var ROOT = '../traces/origin_traces/';

// flowSize 1k, 10k, 100k
var flowSizeArr = [1000, 10000, 100000];
var flowSizeObj;

// packetSize 100B, 1k, 10k
var packetSizeArr = [100, 1000, 10000];
var packetSizeObj;

// packetInterval 1ms, 10ms, 100ms, 1000ms
var packetIntervalArr = [1, 10, 100, 1000];
var packetIntervalObj;

// count protos
var protos = {
    'HTTP': 1
};

function normalize(arr, obj) {

    var sum = 0,
        array= [],
        val;

    for (var i = 0, len = arr.length; i < len; i++) {
        val = arr[i];
        if (!(val in obj)) {
            obj[val] = 0;
        }
        sum += obj[val];
        obj[val] = sum;
    }
    console.log(sum);

    for (var x in obj) {
        obj[x] /= sum;
        console.log(obj[x]);
        array.push({
            value: parseInt(x),
            cdf: obj[x]
        });
    }

    return array;
}

function count(val, arr, obj) {
    
    for (var i = 0, len = arr.length; i < len; i++) {
        if (val <= arr[i]) {
            val = arr[i];
            break;
        }
    }

    if (val > arr[len-1]) {
        val = arr[len-1];
    }
    
    if (val in obj) {
        obj[val]++;
    } else {
        obj[val] = 1;
    }
}

function calculateProtoCDF(dirname) {
    
    var files = fs.readdirSync(dirname),
        filename, content, 
        flowSize, packetSize, prevTime;

    for (var i = 0, leni= files.length; i < leni; i++) {

        filename = dirname + '/' + files[i];
        console.log('processing ', filename);
        content = fs.readFileSync(filename, 'utf-8').split('\n');

        flowSize = 0;
        prevTime = 0;
        for (var j = 0, lenj = content.length; j < lenj; j++) {
            line = content[j].split(' ');
            if (line.length > 2) {
                
                // count packet size
                packetSize = parseInt(line[3]);
                flowSize += packetSize;
                count(packetSize, packetSizeArr, packetSizeObj);

                // count packet interval
                count(parseFloat(line[2]) - prevTime, packetIntervalArr, packetIntervalObj);
                prevTime = parseFloat(line[2]);
            }
        } 

        // count flow size
        count(flowSize, flowSizeArr, flowSizeObj);
    }

    // normalize

    return {
        flowSize: normalize(flowSizeArr, flowSizeObj),
        packetSize: normalize(packetSizeArr, packetSizeObj),
        packetInterval: normalize(packetIntervalArr, packetIntervalObj)
    };
}

function calculateCDF() {

    var dir = fs.readdirSync(ROOT),
        CDFRules = {};

    for (var i = 0, len = dir.length; i < len; i++) {

        if (dir[i] in protos) {

            // reset counter
            flowSizeObj = {};
            packetSizeObj = {};
            packetIntervalObj = {};

            // calculate CDF statistics
            dirname = ROOT + dir[i];
            rule = calculateProtoCDF(dirname);
            CDFRules[dir[i]] = rule;
        }
    }

    // output to JSON file

    fs.writeFile('./CDF.json', JSON.stringify(CDFRules), function (err) {
        if (err) {
            console.log('[ERROR] While generate CDF.json');
        } else {
            console.log('[SUCC] generate CDF.json successfully');
        }
    });
}

calculateCDF();
